/// Message对象的数据库操作

#include "mysql.hpp"
#include "message.hxx"
#include "message-odb.hxx"


namespace mag
{
class MessageTable{
    public:
        using ptr = std::shared_ptr<MessageTable>;
        MessageTable(const std::shared_ptr<odb::core::database> &db): _db(db){}
        ~MessageTable(){}

        ///////////////////////////////
        ///插入消息
        //////////////////////////////
        bool insert(Message &msg){
            try {
                odb::transaction trans(_db->begin());
                _db->persist(msg);
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("新增消息失败 {}:{}！", msg.message_id(),e.what());
                return false;
            }
            return true;
        }

        ////////////////////////////////////
        ///删除指定会话的所有消息
        ////////////////////////////////////
        bool remove(const std::string &ssid){
            try{
                odb::transaction trans(_db->begin());
                typedef odb::query<Message> query;
                typedef odb::result<Message> result;
                _db->erase_query<Message>(query::session_id == ssid);
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("删除会话所有消息失败 {}:{}！", ssid, e.what());
                return false;
            }
            return true;
        }
        ////////////////////////////////////
        ///获取指定会话的最近消息
        ////////////////////////////////////
        std::vector<Message> recent(const std::string &ssid, int count) {
            std::vector<Message> res;
            try {
                odb::transaction trans(_db->begin());
                typedef odb::query<Message> query;
                typedef odb::result<Message> result;
                std::stringstream cond;
                cond << "session_id='" << ssid << "' ";
                cond << "order by create_time desc limit " << count;
                result r(_db->query<Message>(cond.str()));
                for (result::iterator i(r.begin()); i != r.end(); ++i) {
                    res.push_back(*i);
                }
                std::reverse(res.begin(), res.end());
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("获取最近消息失败:{}-{}-{}！", ssid, count, e.what());
            }
            return res;
        }

        ////////////////////////////////////
        ///获取指定时间区间内的消息
        ////////////////////////////////////
        std::vector<Message> range(const std::string &ssid, 
        boost::posix_time::ptime &stime, 
        boost::posix_time::ptime &etime) {
        std::vector<Message> res;
        try {
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;
            result r(_db->query<Message>(query::session_id == ssid && 
                query::create_time >= stime &&
                query::create_time <= etime));
            for (result::iterator i(r.begin()); i != r.end(); ++i) {
                res.push_back(*i);
            }
            trans.commit();
        }catch (std::exception &e) {
            LOG_ERROR("获取区间消息失败:{}-{}:{}-{}！", ssid, 
                boost::posix_time::to_simple_string(stime), 
                boost::posix_time::to_simple_string(etime), e.what());
        }
        return res;
    }

    private:
        std::shared_ptr<odb::core::database> _db; 
};
}